/*
 * Controller test class
 * Author: Jonathan Forbes
 * TCSS 360 (Group project) Spring 2013 
 * University of Washington
 */
package View;

import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.Frame;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Enumeration;
import java.util.List;

import javax.swing.AbstractButton;
import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.ButtonGroup;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities;
import javax.swing.border.Border;

import Model.Controller;
import Model.Paper;
import Model.User;
import View.ViewReview;

/**
 * Class for the SubProgramChair tab.
 * 
 * @author Jonathan Forbes
 * @version 1.0
 */
public class SubprogramChair extends JPanel {

	private static final long serialVersionUID = -4848394766053559673L;
	private Controller controller;
	private ScrollPane scroll;

	private JLabel reviewsDate;
	private JLabel recomendationsDate;
	private Paper selectedPaper;
	private JComboBox userComboList;
	private Frame frame;

	// Label for JCombo Box
	private JLabel userLabel;

	//Labels inside the Asign SPC popup descriptionj
	private JLabel userFullnameDescr;
	private JLabel userLoginDescr;
	private JLabel userEmailDescr;

	//Labels inside the Asign SPC popup to hold information about the user selected
	private JLabel userFullname;
	private JLabel userLogin;
	private JLabel userEmail;

	//List for JCombo box to select User for SPC
	private List <String> UserUniqeLogin;
	private List <String> UserNames;
	private List <String> UserEmail;

	//Buttons for assigning SPC
	private JButton btnAssignReviewerNOW;
	private JButton btnCancel;

	private User currentlySelectedUser;

	/**
	 * Initialize fields.
	 * 
	 * @param control is the Controller from Model package.
	 */
	public SubprogramChair(Controller control) {
		controller = control;
		scroll = new ScrollPane(controller, "spc");
		reviewsDate = new JLabel(" ");
		recomendationsDate = new JLabel(" ");
		userFullname = new JLabel(" ");
		userLogin = new JLabel(" ");
		userEmail = new JLabel(" ");
		UserUniqeLogin = new ArrayList<String>();
		UserNames = new ArrayList<String>();
		UserEmail = new ArrayList<String>();
		userFullnameDescr = new JLabel("Full Name: ");
		userLoginDescr = new JLabel("Unique Login: ");
		userEmailDescr = new JLabel("Email Adress: ");
		userLabel = new JLabel("Users: ");
		btnAssignReviewerNOW = new JButton("Assign Reviewer");
		btnCancel = new JButton("Cancel"); 
		setup();
	}

	/**
	 * Sets up the basic look and catch selection change from JTable in JScrollPane
	 * by utilizing propertyChangeListener.
	 */
	private void setup() {
		final JLabel flag = new JLabel("spc");

		/*
		  Using property change listener to catch list selection changes in ScrollPane.
		  By passing in JLabel to ScrollPane, if setText is changed, JLabels on 
		  PC tab will change accordingly.
		 */
		flag.addPropertyChangeListener(new PropertyChangeListener(){
			@Override
			public void propertyChange(PropertyChangeEvent e) {
				if (e.getSource() == flag && setSelectedPaper()) {
					for (Paper spcPapers : controller.getCurrentUser().getSPCPapers()) {
						if ( selectedPaper.getUniqueCode() == spcPapers.getUniqueCode()) {//Paper match

							//Set Review Deadline
							int rev_day = spcPapers.getConference().getReviewsDeadline().getDateDay();
							int rev_month = spcPapers.getConference().getReviewsDeadline().getDateMonth();
							int rev_year = spcPapers.getConference().getReviewsDeadline().getDateYear();
							reviewsDate.setText(rev_month+ "/" + rev_day + "/" + rev_year);

							//set Recommendation Deadline
							int rec_day = spcPapers.getConference().getNotifyAuthorsDeadline().getDateDay();
							int rec_month = spcPapers.getConference().getNotifyAuthorsDeadline().getDateMonth();
							int rec_year = spcPapers.getConference().getNotifyAuthorsDeadline().getDateYear();
							recomendationsDate.setText(rec_month  + "/" +rec_day  + "/" + rec_year);
						}
					}
				}
			} //propertyChange
		});

		scroll.setFlag(flag);
		JScrollPane pane = scroll.getScrollPane();
		pane.setWheelScrollingEnabled(true);

		setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
		add(pane);
		add(createContainer("Review Deadline: ", reviewsDate));
		add(createContainer("Recommendation Deadline: ", recomendationsDate));
		add(btns());
	} //setup

	/**
	 * Formatting the buttons and labels to a certain look using FlowLayout.
	 * 
	 * @return the Container containing both label and button.
	 */
	private Container createContainer(String labelname, Container theContainer) {
		Container flow = new JPanel(new FlowLayout(FlowLayout.CENTER));
		JLabel lbl = new JLabel(labelname);
		flow.add(lbl);
		flow.add(theContainer);
		return flow;
	}

	/**
	 * Formatting the buttons to a certain look using FlowLayout as well as setting
	 * up their actionListener functionality when the buttons are clicked.
	 * 
	 * @return the Container containing the buttons.
	 */
	private Container btns() {
		Container contain = new JPanel(new FlowLayout(FlowLayout.CENTER));
		final JButton btnAssign = new JButton("Assign Reviewer");
		final JButton btnDownloadPaper = new JButton("Download Paper");             // btnViewRationale
		final JButton btnRecommendation = new JButton("Make/Edit Recommendation");  // btnApproveReject
		final JButton btnViewReviews = new JButton("View Reviews");
		final JButton btnDownloadEmails = new JButton("Download Reviewer Emails");

		btnAssignReviewerNOW.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				if (e.getSource() == btnAssignReviewerNOW) {
					if(userComboList.getSelectedIndex() != -1) {
						controller.assignReviewer(selectedPaper, currentlySelectedUser);
						JOptionPane.showMessageDialog(null, "The User " +currentlySelectedUser.getfullname() + " has been set as a Reviewer for this paper."); 
						frame.dispose();
					}
					else {
						JOptionPane.showMessageDialog(null, "Please select a user from the pull down menu to assign them as program chair for this manuscript."); 
					}
				}
			} //actionPerformed
		});

		btnCancel.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				if (e.getSource() == btnCancel) {
					frame.dispose();
					clearUserNameLists();
				}
			} //actionPerformed
		});
		btnAssign.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				if (e.getSource() == btnAssign && setSelectedPaper()) {
					final List<User> theUsers = controller.getUserList();
					clearUserNameLists();

					//Populate the User String list for the Conference JComboBox
					for(int i = 0; i < theUsers.size(); i++) {
						if(!theUsers.get(i).getLogin().equals(selectedPaper.getAuthor().getLogin()) && notACurrentReviewer(theUsers.get(i))) {//Do not include the author,                            NEED TO ADD DUPLICATE REVIEWERS TO DISALLOW
							UserUniqeLogin.add(theUsers.get(i).getLogin());
							UserNames.add(theUsers.get(i).getfullname());
							UserEmail.add(theUsers.get(i).getEmail());
						}
					}
					final String[] users = Arrays.copyOf(UserNames.toArray(), UserNames.size(), String[].class);

					userComboList = new JComboBox(users);
					userComboList.setSelectedItem(null);
					userComboList.addActionListener(new ActionListener(){

						@Override
						public void actionPerformed(ActionEvent e) {
							JComboBox cb = (JComboBox) e.getSource();
							if (cb == userComboList) {
								int userIndex = cb.getSelectedIndex();
								userFullname.setText(UserNames.get(userIndex));
								userLogin.setText(UserUniqeLogin.get(userIndex));
								userEmail.setText(UserEmail.get(userIndex));
								for(int i = 0; i < theUsers.size(); i++) {
									User tempUser = theUsers.get(i);
									if(tempUser.getfullname() == UserNames.get(userIndex) &&
											tempUser.getEmail() == UserEmail.get(userIndex) &&
											tempUser.getLogin() == UserUniqeLogin.get(userIndex))
										currentlySelectedUser = tempUser;
								}
							}

						}});
					JPanel panel = new JPanel();
					GridBagLayout gridbag = new GridBagLayout();
					GridBagConstraints c = new GridBagConstraints();
					panel.setLayout(gridbag);

					//Set GridBag constraints
					c.gridwidth = GridBagConstraints.REMAINDER; //last
					c.anchor = GridBagConstraints.WEST;
					c.weightx = 1.0;
					panel.setBorder(
							BorderFactory.createCompoundBorder(
									BorderFactory.createTitledBorder("Assign Reviewer to Manuscript"),
									BorderFactory.createEmptyBorder(5,5,5,5)));
					frame = new JFrame();
					JDialog dialog = new JDialog(frame, 
							"Submit A Paper",
							true);
					dialog.setContentPane(panel);
					Dimension windowSize = new Dimension(500, 500);
					frame.setPreferredSize(windowSize);
					dialog.setPreferredSize(windowSize);
					dialog.setDefaultCloseOperation(
							JDialog.DO_NOTHING_ON_CLOSE);



					GridBagConstraints labelConstraints = new GridBagConstraints();
					labelConstraints.insets = new Insets(10,0,0,0);
					labelConstraints.anchor = GridBagConstraints.EAST;
					labelConstraints.gridwidth = GridBagConstraints.RELATIVE; //next-to-last
					labelConstraints.fill = GridBagConstraints.NONE;      //reset to default
					labelConstraints.weightx = 0.0;                       //reset to default

					GridBagConstraints textConstraints = new GridBagConstraints();
					textConstraints.insets = new Insets(10,0,0,0);
					textConstraints.anchor = GridBagConstraints.EAST;
					textConstraints.gridwidth = GridBagConstraints.REMAINDER;     //end row
					textConstraints.fill = GridBagConstraints.HORIZONTAL;
					textConstraints.weightx = 1.0;


					//Add Conference Selection
					panel.add(userLabel, labelConstraints);
					panel.add(userComboList, textConstraints);

					//Add Deadline Display
					panel.add(userFullnameDescr, labelConstraints);
					panel.add(userFullname, textConstraints);

					panel.add(userLoginDescr, labelConstraints);
					panel.add(userLogin, textConstraints);

					panel.add(userEmailDescr, labelConstraints);
					panel.add(userEmail, textConstraints);

					btnAssignReviewerNOW.setPreferredSize(new Dimension(200, 25));
					btnCancel.setPreferredSize(new Dimension(200, 25));
					textConstraints.fill = GridBagConstraints.VERTICAL;

					panel.add(btnAssignReviewerNOW, textConstraints);
					panel.add(btnCancel, textConstraints);

					frame.add(panel);
					frame.setVisible(true);
					frame.setResizable(true);
					frame.pack();
					frame.setLocationRelativeTo(null);
				}
			}
		}); //actionPerformed

		btnRecommendation.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				if (e.getSource() == btnRecommendation && setSelectedPaper()) {
					//review score and comments stored here
					Object[] data = new Object[2];

					final Recommendation rec;
					//check if current user has already recommended this paper
					if (selectedPaper.getRecommendation() == -1) { // not recommended yet
						rec = new Recommendation((JFrame) SwingUtilities.windowForComponent(btnRecommendation),
								"Make/Edit Recommendation", selectedPaper, false);
					} else {
						rec = new Recommendation((JFrame) SwingUtilities.windowForComponent(btnRecommendation),
								"Make/Edit Recommendation", selectedPaper, true);
					}

					rec.start(data);
					data = rec.getData();
					boolean flag = true;
					for (int i = 0; i < data.length; i++) {
						if (data[i] == null) {
							flag = false;
						}
					}

					if (flag) {
						rec.dispose();
						int q1 = (Integer) data[0];
						String comment = (String) data[1];

						controller.modifyRecommendation(selectedPaper, q1, comment);
					}
				}
			} //actionPerformed
		});

		btnViewReviews.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				if (e.getSource() == btnViewReviews) {
					if (scroll.getSelectedRowNum() != -1) {
						Object[] selected = scroll.getRow(scroll.getSelectedRowNum());
						Paper chosen = (Paper)selected[3];
						Paper paper = null;
						for (int i = 0; i < controller.getCurrentUser().getSPCPapers().size(); i++) {
							if (chosen.getUniqueCode() == controller.getCurrentUser().getSPCPapers().get(i).getUniqueCode()) {
								paper = controller.getCurrentUser().getSPCPapers().get(i);
							}
						}
						
//						ViewReview reviews = new ViewReview(paper);
						new ViewReview(paper);

					} else {
						JOptionPane.showMessageDialog(null, "Please select a manuscript to view reviews.",
								"Select Manuscript", JOptionPane.WARNING_MESSAGE);
					}
				}
			} //actionPerformed
		});

		btnDownloadEmails.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				if (e.getSource() == btnDownloadEmails) {
					File file;
					file = controller.getReviewerEmailAddresses();
					JOptionPane.showMessageDialog(null, "Saved " + file.getName()+ " - Email list saved to file."); 
				}
			} //actionPerformed
		});


		contain.add(btnAssign);
		contain.add(btnDownloadPaper);
		contain.add(btnRecommendation);
		contain.add(btnViewReviews);
		contain.add(btnDownloadEmails);
		return contain;
	} //btns


	/**
	 * Used to print out title for tabbed panes.
	 */
	public String getName() {
		return "SubProgram Chair";
	} //getName

	private boolean setSelectedPaper() {
		boolean isPaperSet;
		if (scroll.getSelectedRowNum() != -1) {
			isPaperSet = true;
			Object[] selected = scroll.getRow(scroll.getSelectedRowNum());
			Paper currentPaper = (Paper) selected[3];
			List<Paper> spcPapers = controller.getCurrentUser().getSPCPapers();
			for (int i = 0; i < spcPapers.size(); i++) {
				if (currentPaper.getUniqueCode() == spcPapers.get(i).getUniqueCode()) {
					selectedPaper = currentPaper;
				}
			}
		} else {
			isPaperSet = false;
			JOptionPane.showMessageDialog(null, "Please select a manuscript...",
					"Select Manuscript", JOptionPane.WARNING_MESSAGE);
		}
		return isPaperSet;

	}

	private boolean notACurrentReviewer(User iterated) {
		boolean not_on_the_list = true;
		for (User u : selectedPaper.getReviewers()) {
			if (u.getLogin().equals(iterated.getLogin())) {
				not_on_the_list = false;
			}
		}
		return not_on_the_list;
	}

	private void clearUserNameLists() {
		UserUniqeLogin.clear();
		UserNames.clear();
		UserEmail.clear();
	}

	//==================== Inner class: Recommendation =======================//

	/**
	 * This creates a JDialog containing recommendation functionality.
	 * 
	 * @author Jonathan Forbes
	 * @version UWTCSS 360, Spring 2013. 3-squared-software-systems.
	 */
	private class Recommendation extends JDialog {

		/**
		 * 
		 */
		private static final long serialVersionUID = -3147901723680298672L;
		private Paper paper;
		private boolean prefill;
		private Object[] obj;
		//GUI for user input
		private List<ButtonGroup> group;
		private JTextArea comment;

		/**
		 * Initialize fields.
		 * 
		 * @param frame is the frame this JDialog will center on.
		 * @param title is the title of the JDialog.
		 * @param p is the paper currently selected.
		 */
		private Recommendation(JFrame frame, String title, Paper p, boolean pf) {
			super(frame, title);
			paper = p;
			prefill = pf;
			populateList();
			setup();
		} //constructor

		/**
		 * Populate the list of ButtonGroup based on number of questions
		 * in the review.
		 */
		private void populateList() {
			group = new ArrayList<ButtonGroup>();
			group.add(new ButtonGroup());
		} //populateList

		/**
		 * This sets up the look of the JDialog.
		 */
		private void setup() {
			JPanel main = new JPanel();
			JPanel reviews = new JPanel();
			JLabel title = new JLabel("Recommendation for " + paper.getTitle());
			Border border = BorderFactory.createEmptyBorder(5, 5, 5, 5);
			main.setBorder(border);

			title.setFont(new Font("Serif", Font.BOLD + Font.ITALIC, 24));
			main.setLayout(new BorderLayout());
			main.setPreferredSize(new Dimension(400, 300));
			reviews.setLayout(new BoxLayout(reviews, BoxLayout.Y_AXIS));

			JPanel one = q1();
			JPanel comm = comments();
			Container btns = btns();

			reviews.add(one);
			reviews.add(comm);

			main.add(title, BorderLayout.NORTH);
			main.add(reviews, BorderLayout.CENTER);
			main.add(btns, BorderLayout.SOUTH);

			add(main);
			pack();
		} //setup

		/**
		 * Sets up the labels and radio button for question 1 of the review.
		 * 
		 * @return JPanel containing all components.
		 */
		private JPanel q1() {
			JPanel box = new JPanel();
			Container btn = new JPanel(new FlowLayout(FlowLayout.LEADING));
			box.setLayout(new BorderLayout());
			String q = "<html>Summary Recommendation<br></html>";
			JLabel lblQ = new JLabel(q);

			ButtonGroup q1 = group.get(0);
			JRadioButton c1 = new JRadioButton("5");
			JRadioButton c2 = new JRadioButton("4");
			JRadioButton c3 = new JRadioButton("3");
			JRadioButton c4 = new JRadioButton("2");
			JRadioButton c5 = new JRadioButton("1");

			q1.add(c1);
			q1.add(c2);
			q1.add(c3);
			q1.add(c4);
			q1.add(c5);

			if (prefill) {
				int choice = paper.getRecommendation();
				Enumeration<AbstractButton> btns = q1.getElements();  
				while(btns.hasMoreElements()) {  
					JRadioButton temp = (JRadioButton)btns.nextElement();
					if(Integer.parseInt(temp.getText()) == choice) {  
						temp.setSelected(true);
					}  
				}
			}

			btn.add(c1);
			btn.add(c2);
			btn.add(c3);
			btn.add(c4);
			btn.add(c5);

			box.add(lblQ, BorderLayout.NORTH);
			box.add(btn, BorderLayout.CENTER);
			return box;
		} //q1

		/**
		 * Sets up the JTextArea where the reviewer can type in extra comments
		 * to the author of the paper.
		 * 
		 * @return JPanel containing JScrollPane which contains JTextArea.
		 */
		private JPanel comments() {
			JPanel panel = new JPanel();
			Container lbl = new JPanel(new FlowLayout(FlowLayout.LEADING));
			JLabel lblComm = new JLabel("Rationale:");
			panel.setLayout(new BorderLayout());
			panel.setPreferredSize(new Dimension(100, 200));

			if (prefill) {
				comment = new JTextArea(paper.getRationale());
			} else {
				comment = new JTextArea();
			}

			comment.setEditable(true);
			comment.setLineWrap(true);
			comment.setWrapStyleWord(true);
			JScrollPane text = new JScrollPane(comment);

			lbl.add(lblComm);
			panel.add(lbl, BorderLayout.NORTH);
			panel.add(text, BorderLayout.CENTER);
			return panel;
		} //comments

		/**
		 * Sets up JButtons' action listener and add them to the panel to be
		 * added to the main panel.
		 * 
		 * @return the container containing two buttons with flow layout.
		 */
		private Container btns() {
			Container flow = new JPanel(new FlowLayout(FlowLayout.CENTER));
			final JButton confirm = new JButton("Confirm");
			final JButton cancel = new JButton("Cancel");

			confirm.addActionListener(new ActionListener() {
				@Override
				public void actionPerformed(ActionEvent e) {
					if (e.getSource() == confirm) {

						update();
						boolean check = true;
						for (int i = 0; i < obj.length; i++) {
							if (obj[i] == null) {
								check = false;
							}
						}
						if (!check) {
							JOptionPane.showMessageDialog(null, "Please make sure all fields are filled in.",
									"Incomplete Form", JOptionPane.ERROR_MESSAGE);
							setVisible(true);
						} else {
							setVisible(false);
						}
					}
				}
			});

			cancel.addActionListener(new ActionListener() {
				@Override
				public void actionPerformed(ActionEvent e) {
					if (e.getSource() == cancel) {
						dispose();
					}
				}
			});

			flow.add(confirm);
			flow.add(cancel);
			return flow;
		} //getButtons

		/**
		 * Gets the selected button out of a specified ButtonGroup.
		 * 
		 * @param grp is the ButtonGroup.
		 * @return parsed selected JRadioButton's text.
		 */
		private int getSelected(ButtonGroup grp) {
			String text = null;
			Enumeration<AbstractButton> btns = grp.getElements();  
			while(btns.hasMoreElements()) {  
				JRadioButton temp = (JRadioButton)btns.nextElement();  
				if(temp.isSelected()) {  
					text = temp.getText(); 
					break;
				}  
			} 
			return Integer.parseInt(text);
		} //getSelected

		/**
		 * Populates the object array with user's input.
		 */
		private void update() {
			obj[0] = getSelected(group.get(0));
			obj[1] = comment.getText();
		} //update

		/**
		 * Let other classes gets the updated, populated array of data.
		 * 
		 * @return the Object array with user input.
		 */
		public Object[] getData() {
			return obj;
		} //getData

		/**
		 * This JDialog will be displayed when this method is called.
		 * 
		 * @param getObj is the array that the user input will be stored.
		 */
		public void start(Object[] getObj) {
			obj = getObj;
			setModal(true);
			setLocationRelativeTo(null);
			setVisible(true);
		} //start
	} //Recommendation
}
